home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume25 / crashme < prev    next >
Encoding:
Internet Message Format  |  1991-12-02  |  22.9 KB

  1. Subject:  v25i003:  crashme V1.8 - stress-test your U**X kernel
  2. Newsgroups: comp.sources.unix
  3. Approved: vixie@pa.dec.com
  4.  
  5. Submitted-by: George J Carrette <gjc@mitech.com>
  6. Posting-number: Volume 25, Issue 3
  7. Archive-name: crashme
  8.  
  9. [ I added "all", "clean", and "install" targets to the Makefile.  --mod ]
  10.  
  11. Crashme is a very simple program that tests the operating environment's
  12. robustness by invoking random data as if it were a procedure.  The standard
  13. signals are caught and handled with a setjmp back to a loop which will try
  14. again to produce a fault by executing random data.  [... note that] to
  15. really test a significant portion of an instruction set of a machine you
  16. have to let a test like this run for weeks on end. It was really quite
  17. suprising that so many machines crashed after only a few seconds.
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of shell archive."
  26. # Contents:  README Makefile crashme.1 crashme.c crashme.opt
  27. #   descrip.mms
  28. # Wrapped by vixie@cognition.pa.dec.com on Mon Dec  2 20:21:51 1991
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'README' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'README'\"
  32. else
  33. echo shar: Extracting \"'README'\" \(2845 characters\)
  34. sed "s/^X//" >'README' <<'END_OF_FILE'
  35. Notes for release 1.8 of Crashme. 27-SEP-1991 GJC@MITECH.COM
  36. X
  37. Many people have suggested that the output of previous versions was
  38. far too verbose, and that that was not only anoying but also
  39. effectively slowing down the program. Therefore there is a new argument
  40. available after the subprocess control argument, which is a verboseness
  41. level from 0 to 5. Using a level of 2 will print out only summary
  42. information about the runs. e.g.
  43. X
  44. X$ crashme +2000 666 50 00:30:00 2
  45. Crashme: (c) Copyright 1990, 1991 George J. Carrette
  46. Version: 1.7 25-SEP-1991
  47. Subprocess run for 1800 seconds (0 00:30:00)
  48. Test complete, total real time: 1801 seconds (0 00:30:01)
  49. exit status ... number of cases
  50. X       1100 ...     2
  51. X    3522652 ...     4
  52. X       1036 ...     1
  53. X       1084 ...     7
  54. X       1108 ...    19
  55. X          1 ...   432
  56. X         12 ...   137
  57. X
  58. The table of exit status codes and frequencies is a new interesting
  59. aspect of the test. This test was run on a VMS system, so that we have
  60. a normal process exit 432 times, access violation 137 times,
  61. and reserved operand fault 19 times, etc. As the number of tries goes
  62. up (50 in this case) we would expect that the number of normal process
  63. exits to go down.
  64. X
  65. Here is some output supplied by nik@infonode.ingr.com on one of his machines.
  66. X
  67. Processor : Intergraph Clipper C300 RISC processor
  68. X            16Mb memory + 4k I cache and 4K D cache
  69. X
  70. Operating System: CLIX Version c.5.3.2
  71. X                  derived from AT&T SVR 3.1 with BSD enhancements.
  72. X
  73. Crashme: (c) Copyright 1990, 1991 George J. Carrette
  74. Version: 1.7 25-SEP-1991
  75. Subprocess run for 9000 seconds (0 02:30:00)
  76. Test complete, total real time: 9004 seconds (0 02:30:04)
  77. exit status ... number of cases
  78. X        136 ...     1
  79. X      24576 ...     1
  80. X         14 ...     1
  81. X        138 ...    11
  82. X        135 ...    27
  83. X        140 ...    26
  84. X        132 ...   430
  85. X        139 ...    18
  86. X      12800 ...   567
  87. X
  88. The status values here could be decoded by reading the documentation
  89. for the "wait" system procedure, and looking up the correct part of
  90. the value in the sys_errlist[] array. That is left as an exersize for the 
  91. reader.
  92. X
  93. X------------------------------------------------------------------------
  94. X
  95. To compile, some systems may need #include <sys/types.h>.
  96. X
  97. Also, note the conditionalized code in bad_malloc. If your system
  98. only gets the signal "segmentation violation" then you may need
  99. to consider conditionalizations along this line. 
  100. X
  101. However, on a machine with a segmented address space, that has
  102. X"instructions" in one segment and "data" in another, it is highly
  103. unlikely that the code for setting up and invoking the "void (*badboy)()" 
  104. will have any interesting effect. Nothing other than an easily
  105. handled SIGSEGV will result in the inner testing loop.
  106. X
  107. Some INTEL 80386 and DEC PDP-11 systems would be examples of this situation.
  108. X
  109. X
  110. X
  111. X
  112. X
  113. X
  114. X
  115. X
  116. X
  117. X
  118. X
  119. END_OF_FILE
  120. if test 2845 -ne `wc -c <'README'`; then
  121.     echo shar: \"'README'\" unpacked with wrong size!
  122. fi
  123. # end of 'README'
  124. fi
  125. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  126.   echo shar: Will not clobber existing file \"'Makefile'\"
  127. else
  128. echo shar: Extracting \"'Makefile'\" \(293 characters\)
  129. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  130. DESTROOT=
  131. DESTPATH=usr/local
  132. X
  133. all: crashme
  134. X
  135. clean:
  136. X    -rm -f *.o crashme core *~ *.BAK *.CKP
  137. X
  138. install: crashme crashme.1
  139. X    install -c -s crashme   $(DESTROOT)/$(DESTPATH)/bin/crashme
  140. X    install -c    crashme.1 $(DESTROOT)/$(DESTPATH)/man/man1/crashme.1
  141. X
  142. crashme:    crashme.o
  143. X    cc -o crashme crashme.o
  144. END_OF_FILE
  145. if test 293 -ne `wc -c <'Makefile'`; then
  146.     echo shar: \"'Makefile'\" unpacked with wrong size!
  147. fi
  148. # end of 'Makefile'
  149. fi
  150. if test -f 'crashme.1' -a "${1}" != "-c" ; then 
  151.   echo shar: Will not clobber existing file \"'crashme.1'\"
  152. else
  153. echo shar: Extracting \"'crashme.1'\" \(2430 characters\)
  154. sed "s/^X//" >'crashme.1' <<'END_OF_FILE'
  155. X.TH CRASHME 1C LOCAL 
  156. X.SH NAME
  157. crashme \- test operating environment software robustness
  158. X.SH SYNOPSIS
  159. X.B crashme
  160. X[NBYTES] [SRAND] [NTRYS] [NSUB] [VERBOSE]
  161. X.SH DESCRIPTION
  162. X.I crashme
  163. is a very simple program that tests the operating environment's
  164. robustness by invoking random data as if it were a procedure.
  165. The standard signals are caught and handled with a setjmp back
  166. to a loop which will try again to produce a fault by executing
  167. random data.
  168. X
  169. X.RE
  170. X.SS COMMAND LINE OPTIONS
  171. X.TP 8
  172. X.BI [NBYTES]
  173. The
  174. X.I [NBYTES]
  175. should be an integer, specifying the size of the random data string
  176. in bytes. If given negative then the bytes are printed instead of
  177. being executed. If given with an explicit plus sign then the
  178. storage for the bytes is freshly malloc'ed each time. This can have an
  179. effect on machines with seperate I and D cache mechanisms.
  180. X.TP
  181. X.BI [SRAND]
  182. The 
  183. X.I [SRAND]
  184. is an input seed to the random number generator, passed to srand.
  185. X.TP
  186. X.BI [NTRIES]
  187. The
  188. X.I [NTRIES]
  189. is how many times to loop before exiting normally from the program.
  190. X.TP
  191. X.BI [NSUB]
  192. The
  193. X.I [NSUB] is optional, the number of vfork subprocesses running at once.
  194. If given as negative the number of vfork subprocesses to run, one after
  195. another. If given as a time hrs:mns:scs (hours, minutes, seconds) then
  196. one subprocess will be run to completion, followed by another, until
  197. the time limit has been reached. 
  198. X
  199. When in sequential-subprocess mode there is a 3 minute time limit on
  200. each subprocess. This is to allow the instruction-set-space random
  201. walk to continue when a process bashes itself into an infinite loop.
  202. XFor example, the ntrys can be bashed to a very large number with
  203. nbytes bashed to zero.
  204. X
  205. The SRAND argument is incremented by one for each subprocess.
  206. X
  207. X.TP
  208. X.BI [VERBOSE]
  209. The
  210. X.I [VERBOSE] arg is optional. 0 is the least verbose, 5 the most.
  211. X
  212. X.SH EXAMPLE
  213. This is a suggested test, to run it for a least an hour.
  214. X
  215. crashme +2000 666 100 1:00:00
  216. X
  217. X.SH FILES
  218. crashme.c
  219. X.PD
  220. X.SH DIAGNOSTICS
  221. When a signal is caught the number and nature of the signal is indicated.
  222. X.SH BUGS
  223. Not all signals are caught, and the state of the user program/process
  224. enviroment can be sufficiently damaged such that the program terminates
  225. before going through all [NTRIES] operations.
  226. X
  227. Beware: This program can crash your computer if the
  228. operating system or hardware of same is buggy. User data may be lost.
  229. X.SH AUTHOR
  230. George J Carrette. GJC\@MITECH.COM
  231. X.SH VERSION
  232. X1.8 27-SEP-1991
  233. END_OF_FILE
  234. if test 2430 -ne `wc -c <'crashme.1'`; then
  235.     echo shar: \"'crashme.1'\" unpacked with wrong size!
  236. fi
  237. # end of 'crashme.1'
  238. fi
  239. if test -f 'crashme.c' -a "${1}" != "-c" ; then 
  240.   echo shar: Will not clobber existing file \"'crashme.c'\"
  241. else
  242. echo shar: Extracting \"'crashme.c'\" \(13087 characters\)
  243. sed "s/^X//" >'crashme.c' <<'END_OF_FILE'
  244. X/* crashme: Create a string of random bytes and then jump to it.
  245. X            crashme <nbytes> <srand> <ntrys> [nsub] */
  246. X
  247. char *crashme_version = "1.8 27-SEP-1991";
  248. X
  249. X/*
  250. X *             COPYRIGHT (c) 1990, 1991 BY       *
  251. X *  GEORGE J. CARRETTE, CONCORD, MASSACHUSETTS.  *
  252. X *             ALL RIGHTS RESERVED               *
  253. X
  254. Permission to use, copy, modify, distribute and sell this software
  255. and its documentation for any purpose and without fee is hereby
  256. granted, provided that the above copyright notice appear in all copies
  257. and that both that copyright notice and this permission notice appear
  258. in supporting documentation, and that the name of the author
  259. not be used in advertising or publicity pertaining to distribution
  260. of the software without specific, written prior permission.
  261. X
  262. THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  263. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  264. HE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  265. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  266. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  267. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  268. SOFTWARE.
  269. X
  270. A signal handler is set up so that in most cases the machine exception
  271. generated by the illegal instructions, bad operands, etc in the procedure
  272. made up of random data are caught; and another round of randomness may
  273. be tried. Eventually a random instruction may corrupt the program or
  274. the machine state in such a way that the program must halt. This is
  275. a test of the robustness of the hardware/software for instruction
  276. fault handling.
  277. X
  278. Note: Running this program just a few times, using total CPU time of
  279. less than a few seconds SHOULD NOT GIVE YOU ANY CONFIDENCE in system
  280. robustness. Having it run for hours, with tens of thousands of cases
  281. would be a different thing.
  282. X
  283. Comments may be addressed to the author at GJC@MITECH.COM
  284. X
  285. See the documentation in crashme.1 or read this code for a description
  286. of command line arguments to this program.
  287. X
  288. Version Date         Description
  289. X----------------------------------------------------------------------
  290. X 1.0    early 1990   initial hack.
  291. X 1.1    19-SEP-1990  added more signals and an alarm to abort looping.
  292. X 1.2    25-JUN-1991  added [nsub] to vfork multiple subprocesses of self.
  293. X 1.3    14-AUG-1991  +nbytes malloc option, and -nsub option.
  294. X 1.4    29-AUG-1991  fix +nbytes (subproc). Add time-driven nprocs. SIGINT.
  295. X 1.5     3-SEP-1991  added alarm subprocess monitor to vfork_main.
  296. X 1.6     5-SEP-1991  some systems don't have vfork, so use fork by default.
  297. X 1.7    25-SEP-1991  verboseness level, exit summary report.
  298. X 1.8      -SEP-1991  address page protection issues on badboy.
  299. X
  300. Suggested test: At least let the thing run the length of your lunch break,
  301. in this case 1 hour, 10 minutes, and 30 seconds.
  302. X
  303. X  crashme +2000 666 100 1:10:30 2
  304. X
  305. X
  306. X                        CRASH REPORTS
  307. X
  308. Date,               Machine              Crashme        Reported 
  309. Crashme Ver   Make    Model OS Version   Arguments      by:        
  310. X------------------------------------------------------------------------------
  311. X10-JUL-90 1.0 SUN     4/110 4.1          1000 20 200    GJC@paradigm.com
  312. X10-JUL-90 1.0 SUN     4/280 4.0.3        1000 20 200    GJC@paradigm.com
  313. X31-JUL-90 1.0 DIGITAL DECstation 3100    100 10 10000   GAVRON@ARIZONA.EDU
  314. X31-JUL-90 1.0 IBM     RT                 100 10 10000   GAVRON@ARIZONA.EDU
  315. X 1-AUG-90 1.0 DIGITAL DECstation 5000    10000 230 1000 hudgens@scri.fsu.edu
  316. X 3-AUG-90 1.0 Alliant FX/2800                           SJA@SIRIUS.HUT.FI
  317. X27-JUN-91 1.2 SUN     4/110 4.1.1        10 1000 10     LPH@PARADIGM.COM   
  318. X27-JUN-91 1.2 SUN     4/110 4.1.1        1000 20 200 10 LPH@PARADIGM.COM   
  319. X29-JUN-91 1.2 SUN     4/40C 4.1.1        9 29748 5877 4 jon@uk.ac.oxford.robots
  320. X29-JUN-91 1.2 SUN     4/60 4.1.1         9 29748 5877 4 jon@uk.ac.oxford.robots
  321. X29-JUN-91 1.2 SUN     4/100 4.1.1        9 29748 5877 4 jon@uk.ac.oxford.robots
  322. X29-JUN-91 1.2 SUN     4/65 4.1.1         9 29748 5877 4 jon@uk.ac.oxford.robots
  323. X18-JUL-91 1.2 SGI     Iris4d Unix 3.3.2  1000 $$ 1000 4 tsacas@ilog.ilog.fr
  324. X29-JUL-91 1.1 IBM     RS/6000 AIX 1.3    script         brandis@inf.ethz.ch
  325. X 5-SEP-91 1.6 IBM     RS/6000-320 AIX 3.1.5 +2000 666 50 40:00:00 LPH
  326. X26-SEP-91 1.8 Nixdorf Targon/35 TOS3.3   script         petri@ibr.cs.tu-bs.de
  327. X
  328. Notes: Crashme V1.0 {1000 20 200} used to down the SUN 4/110. V1.2 does *not*
  329. crash SUNOS 4.1.1 on the same arguments. Although using the extra argument
  330. for subprocesses it will crash, with the console reporting:
  331. X"Bad Trap, Bad Kernel Read Fault, Bus error. Reboot" 
  332. X
  333. Script means invoking file with many calls to crashme such as this:
  334. X#/bin/csh
  335. crashme 1020 234 500 &
  336. crashme 394 38484 5723 &
  337. crashme 3784 474 474 &
  338. crashme 437 4747 38 &
  339. crashme 47848 4745 123 &
  340. crashme 4747 4747 3463 &
  341. crashme 474 46464 262 &
  342. crashme 37 3644 3723 &
  343. crashme 374 46464 22 &
  344. crashme 3747 464 363 &
  345. crashme 347 4747 44 &
  346. crashme 37374 374 66 &
  347. crashme 3737 474 4444 &
  348. X
  349. The 4-argument case of crashme could likely do as well as executing
  350. a script.
  351. X
  352. X*/
  353. X
  354. X
  355. X#include <stdio.h>
  356. X#include <signal.h>
  357. X#include <setjmp.h>
  358. X#include <time.h>
  359. X
  360. X#ifdef pyr
  361. X#include <sys/mman.h>
  362. X#include <sys/types.h>
  363. X#include <sys/param.h>
  364. X#include <sys/vmmac.h>
  365. X#define strchr index
  366. X#endif
  367. X
  368. long nbytes,nseed,ntrys;
  369. long malloc_flag = 0;
  370. unsigned char *the_data;
  371. char *note_buffer;
  372. char *notes;
  373. X
  374. long verbose_level = 5;
  375. X
  376. void note(level)
  377. X     long level;
  378. X{if (level > verbose_level) return;
  379. X strcat(note_buffer,"\n");
  380. X fputs(note_buffer,stdout);}
  381. X
  382. jmp_buf again_buff;
  383. X
  384. void (*badboy)();
  385. X
  386. unsigned char *bad_malloc(n)
  387. X     long n;
  388. X{unsigned char *data;
  389. X data = (unsigned char *) malloc(n);
  390. X#ifdef pyr
  391. X if (mprotect(((int)data/PAGSIZ)*PAGSIZ, (n/PAGSIZ+1)*PAGSIZ,
  392. X          PROT_READ|PROT_WRITE|PROT_EXEC))
  393. X   perror("mprotect");
  394. X#endif
  395. X return(data);}
  396. X
  397. void again_handler(sig, code, scp, addr)
  398. X     int sig, code;
  399. X     struct sigcontext *scp;
  400. X     char *addr;
  401. X{char *ss;
  402. X switch(sig)
  403. X   {case SIGILL: ss =   " illegal instruction"; break;
  404. X    case SIGTRAP: ss =   " trace trap"; break;
  405. X    case SIGFPE: ss =   " arithmetic exception"; break;
  406. X    case SIGBUS: ss =  " bus error"; break;
  407. X    case SIGSEGV: ss =  " segmentation violation"; break;
  408. X    case SIGIOT: ss = " IOT instruction"; break;
  409. X    case SIGEMT: ss = " EMT instruction"; break;
  410. X    case SIGALRM: ss = " alarm clock"; break;
  411. X    case SIGINT:  ss = " interrupt"; break;
  412. X    default: ss = "";}
  413. X sprintf(notes,"Got signal %d%s",sig,ss);
  414. X note(5);
  415. X longjmp(again_buff,3);}
  416. set_up_signals()
  417. X{signal(SIGILL,again_handler);
  418. X signal(SIGTRAP,again_handler);
  419. X signal(SIGFPE,again_handler);
  420. X signal(SIGBUS,again_handler);
  421. X signal(SIGSEGV,again_handler);
  422. X signal(SIGIOT,again_handler);
  423. X signal(SIGEMT,again_handler);
  424. X signal(SIGALRM,again_handler);
  425. X signal(SIGINT,again_handler);}
  426. X
  427. compute_badboy()
  428. X{long j,n;
  429. X n = (nbytes < 0) ? - nbytes : nbytes;
  430. X if (malloc_flag == 1)
  431. X   {the_data = bad_malloc(n);
  432. X    badboy = (void (*)()) the_data;}
  433. X for(j=0;j<n;++j) the_data[j] = (rand() >> 7) & 0xFF;
  434. X if (nbytes < 0)
  435. X   {sprintf(notes,"Dump of %ld bytes of data",n);
  436. X    note(1);
  437. X    for(j=0;j<n;++j)
  438. X      {fprintf(stdout,"%3d",the_data[j]);
  439. X       if ((j % 20) == 19) putc('\n',stdout); else putc(' ',stdout);}
  440. X    putc('\n',stdout);}}
  441. X
  442. try_one_crash()
  443. X{if (nbytes > 0)
  444. X   (*badboy)();
  445. X else if (nbytes == 0)
  446. X   while(1);}
  447. X
  448. char *subprocess_ind = "subprocess";
  449. main(argc,argv)
  450. X     int argc; char **argv;
  451. X{long nsubs,hrs,mns,scs,tflag,j,m;
  452. X note_buffer = (char *) malloc(512);
  453. X notes = note_buffer;
  454. X if ((argc == 7) &&
  455. X     (strcmp(argv[6],subprocess_ind) == 0))
  456. X   {sprintf(note_buffer,"Subprocess %s: ",argv[4]);
  457. X    notes = note_buffer + strlen(note_buffer);
  458. X    verbose_level = atol(argv[5]);
  459. X    sprintf(notes,"starting");
  460. X    note(3);
  461. X    old_main(4,argv);}
  462. X else if (argc == 4)
  463. X   old_main(4,argv);
  464. X else if ((argc == 5) || (argc == 6))
  465. X   {if (argc == 6)
  466. X      verbose_level = atol(argv[5]);
  467. X    copyright_note(1);
  468. X    if (argc < 7)
  469. X      m = argc;
  470. X    else
  471. X      m = 6;
  472. X    strcpy(notes,"crashme");
  473. X    for(j=1;j<m;++j)
  474. X      {strcat(notes," ");
  475. X       strcat(notes,argv[j]);}
  476. X    note(1);
  477. X    if (strchr(argv[4],':'))
  478. X      {sscanf(argv[4],"%d:%d:%d",&hrs,&mns,&scs);
  479. X       tflag = 1;
  480. X       nsubs = (((hrs * 60) + mns) * 60) + scs;
  481. X       sprintf(notes,"Subprocess run for %d seconds (%d %02d:%02d:%02d)",
  482. X           nsubs, hrs / 24, hrs % 24,mns,scs);}
  483. X    else
  484. X      {tflag = 0;
  485. X       nsubs = atol(argv[4]);
  486. X       sprintf(notes,"Creating %d crashme subprocesses",nsubs);}
  487. X    note(1);
  488. X    vfork_main(tflag,nsubs,argv[0],argv[1],atol(argv[2]),argv[3]);}
  489. X else
  490. X   {sprintf(notes,"crashme <nbytes> <srand> <ntrys> [nsub] [verbose]");
  491. X    note(0);}}
  492. X
  493. copyright_note(n)
  494. X     long n;
  495. X{sprintf(notes,"Crashme: (c) Copyright 1990, 1991 George J. Carrette");
  496. X note(n);
  497. X sprintf(notes,"Version: %s",crashme_version);
  498. X note(n);}
  499. X
  500. old_main(argc,argv)
  501. X     int argc;
  502. X     char **argv;
  503. X{copyright_note(3);
  504. X nbytes = atol(argv[1]);
  505. X if (argv[1][0] == '+') malloc_flag = 1;
  506. X nseed = atol(argv[2]);
  507. X ntrys = atol(argv[3]);
  508. X sprintf(notes,"crashme %s%ld %ld %ld",
  509. X     (malloc_flag == 0) ? "" : "+",nbytes,nseed,ntrys);
  510. X note(3);
  511. X if (malloc_flag == 0)
  512. X   {the_data = bad_malloc((nbytes < 0) ? -nbytes : nbytes);
  513. X    badboy = (void (*)()) the_data;
  514. X    sprintf(notes,"Badboy at %d. 0x%X",badboy,badboy);
  515. X    note(3);}
  516. X srand(nseed);
  517. X badboy_loop();}
  518. X
  519. badboy_loop()
  520. X{int i;
  521. X for(i=0;i<ntrys;++i)
  522. X   {compute_badboy();
  523. X    if (malloc_flag == 1)
  524. X      sprintf(notes,"try %ld, Badboy at %d. 0x%X",i,badboy,badboy);
  525. X    else
  526. X      sprintf(notes,"try %ld",i);
  527. X    note(5);
  528. X    if (setjmp(again_buff) == 3)
  529. X      {sprintf(notes,"Barfed");
  530. X       note(5);}
  531. X    else
  532. X      {set_up_signals();
  533. X       alarm(10);
  534. X       try_one_crash();
  535. X       sprintf(notes,"didn't barf!");
  536. X       note(5);}}}
  537. X
  538. long monitor_pid = 0;
  539. long monitor_period = 10;
  540. long monitor_limit =  18; /* 3 minute limit on a subprocess */
  541. long monitor_count = 0;
  542. long monitor_active = 0;
  543. X
  544. void monitor_fcn(sig, code, scp, addr)
  545. X     int sig, code;
  546. X     struct sigcontext *scp;
  547. X     char *addr;
  548. X{long status;
  549. X signal(SIGALRM,monitor_fcn);
  550. X alarm(monitor_period);
  551. X if (monitor_active)
  552. X   {++monitor_count;
  553. X    if (monitor_count >= monitor_limit)
  554. X      {sprintf(notes,"time limit reached on pid %d 0x%X. using kill.",
  555. X           monitor_pid,monitor_pid);
  556. X       note(3);
  557. X       status = kill(monitor_pid,SIGKILL);
  558. X       if (status < 0)
  559. X     {sprintf(notes,"failed to kill process");
  560. X      note(3);}
  561. X       monitor_active = 0;}}}
  562. X
  563. struct status_list
  564. X{long status;
  565. X long count;
  566. X struct status_list *next;};
  567. X
  568. struct status_list *slist = NULL;
  569. X
  570. record_status(n)
  571. X     long n;
  572. X{struct status_list *l;
  573. X for(l=slist;l != NULL; l = l->next)
  574. X   if (n == l->status)
  575. X     return(++l->count);
  576. X l = (struct status_list *) malloc(sizeof(struct status_list));
  577. X l->count = 1;
  578. X l->status = n;
  579. X l->next = slist;
  580. X slist = l;
  581. X return(1);}
  582. X
  583. summarize_status()
  584. X{struct status_list *l;
  585. X sprintf(notes,"exit status ... number of cases");
  586. X note(2);
  587. X for(l=slist;l != NULL; l = l->next)
  588. X   {sprintf(notes,"exit status ... number of cases");
  589. X    sprintf(notes,"%11d ... %5d",l->status,l->count);
  590. X    note(2);}}
  591. X
  592. vfork_main(tflag,nsubs,cmd,nb,sr,nt)
  593. X     long tflag,nsubs,sr;
  594. X     char *cmd,*nb,*nt;
  595. X{long j,status,pid,n,seq,total_time,dys,hrs,mns,scs;
  596. X char arg2[20],arg4[20],arg5[20];
  597. X time_t before_time,after_time;
  598. X if (tflag == 1)
  599. X   {seq = 1;
  600. X    n = 100000000;}
  601. X else if (nsubs < 0)
  602. X   {n = -nsubs;
  603. X    seq = 1;}
  604. X else
  605. X   {n = nsubs;
  606. X    seq = 0;}
  607. X if (seq == 1)
  608. X   {signal(SIGALRM,monitor_fcn);
  609. X    alarm(monitor_period);}
  610. X time(&before_time);
  611. X sprintf(arg5,"%d",verbose_level);
  612. X for(j=0;j<n;++j)
  613. X   {sprintf(arg2,"%d",sr+j);
  614. X    sprintf(arg4,"%d",j+1);
  615. X#ifdef VMS
  616. X    status = vfork();
  617. X#else
  618. X    status = fork();
  619. X#endif
  620. X    if (status == 0)
  621. X      {status = execl(cmd,cmd,nb,arg2,nt,arg4,arg5,subprocess_ind,0);
  622. X       if (status == -1)
  623. X     {perror(cmd);
  624. X      exit(1);}}
  625. X    else if (status < 0)
  626. X      perror(cmd);
  627. X    else
  628. X      {sprintf(notes,"pid = %d 0x%X (subprocess %d)",status,status,j+1);
  629. X       note(3);
  630. X       if (seq == 1)
  631. X     {monitor_pid = status;
  632. X      monitor_count = 0;
  633. X      monitor_active = 1;
  634. X      while((pid = wait(&status)) > 0)
  635. X        {monitor_active = 0;
  636. X         sprintf(notes,"pid %d 0x%X exited with status %d",pid,pid,status);
  637. X         note(3);
  638. X         record_status(status);}}
  639. X       if (tflag == 1)
  640. X     {time(&after_time);
  641. X      total_time = after_time - before_time;
  642. X      if (total_time >= nsubs)
  643. X        {sprintf(notes,"Time limit reached after run %d",j+1);
  644. X         note(2);
  645. X         break;}}}}
  646. X if (seq == 0)
  647. X   while((pid = wait(&status)) > 0)
  648. X     {sprintf(notes,"pid %d 0x%X exited with status %d",pid,pid,status);
  649. X      note(3);
  650. X      record_status(status);}
  651. X time(&after_time);
  652. X total_time = after_time - before_time;
  653. X scs = total_time;
  654. X mns = scs / 60;
  655. X hrs = mns / 60;
  656. X dys = hrs / 24;
  657. X scs = scs % 60;
  658. X mns = mns % 60;
  659. X hrs = hrs % 24;
  660. X sprintf(notes,
  661. X     "Test complete, total real time: %d seconds (%d %02d:%02d:%02d)",
  662. X     total_time,dys,hrs,mns,scs);
  663. X note(1);
  664. X summarize_status();}
  665. X
  666. END_OF_FILE
  667. if test 13087 -ne `wc -c <'crashme.c'`; then
  668.     echo shar: \"'crashme.c'\" unpacked with wrong size!
  669. fi
  670. # end of 'crashme.c'
  671. fi
  672. if test -f 'crashme.opt' -a "${1}" != "-c" ; then 
  673.   echo shar: Will not clobber existing file \"'crashme.opt'\"
  674. else
  675. echo shar: Extracting \"'crashme.opt'\" \(84 characters\)
  676. sed "s/^X//" >'crashme.opt' <<'END_OF_FILE'
  677. X! VMS LINKER OPTIONS FILE
  678. IDENTIFICATION = "CRASHME V1.8"
  679. SYS$LIBRARY:VAXCRTL/SHARE
  680. END_OF_FILE
  681. if test 84 -ne `wc -c <'crashme.opt'`; then
  682.     echo shar: \"'crashme.opt'\" unpacked with wrong size!
  683. fi
  684. # end of 'crashme.opt'
  685. fi
  686. if test -f 'descrip.mms' -a "${1}" != "-c" ; then 
  687.   echo shar: Will not clobber existing file \"'descrip.mms'\"
  688. else
  689. echo shar: Extracting \"'descrip.mms'\" \(690 characters\)
  690. sed "s/^X//" >'descrip.mms' <<'END_OF_FILE'
  691. X! VMS MAKEFILE (for MMS)
  692. X!
  693. X
  694. CFLAGS = /DEBUG/LIST/SHOW=(NOSOURCE)/MACHINE/OPTIMIZE=(NOINLINE)/STANDARD=PORTABLE
  695. X
  696. crashme.exe depends_on crashme.obj
  697. X link crashme.obj,crashme.opt/opt
  698. X ! re-execute the next line in your superior process:
  699. X crashme == "$" + f$env("DEFAULT") + "CRASHME"
  700. X
  701. crashme-dbg.exe depends_on crashme.obj
  702. X link/debug/exe=crashme-dbg.exe crashme.obj,crashme.opt/opt
  703. X
  704. X! note: do not use continuation character here.
  705. DIST_FILES = crashme.1,crashme.c,makefile,descrip.mms,crashme.opt,read.me,shar.db
  706. X
  707. crashme.shar depends_on $(DIST_FILES)
  708. X minishar crashme.shar shar.db
  709. X
  710. crashme.1_of_1 depends_on $(DIST_FILES)
  711. X define share_max_part_size 1000
  712. X vms_share $(DIST_FILES) crashme
  713. END_OF_FILE
  714. if test 690 -ne `wc -c <'descrip.mms'`; then
  715.     echo shar: \"'descrip.mms'\" unpacked with wrong size!
  716. fi
  717. # end of 'descrip.mms'
  718. fi
  719. echo shar: End of shell archive.
  720. exit 0
  721.